package main

import (
	"fmt"
	"sync"
)

var wg = sync.WaitGroup{}

func main() {
	groupCnt := 3 // 3个一组

	dogChan := make(chan struct{}, 1)
	catChan := make(chan struct{}, 1)
	fishChan := make(chan struct{}, 1)

	wg.Add(3)

	//start
	dogChan <- struct{}{}

	go dog(dogChan, groupCnt, catChan)   //通知cat
	go cat(catChan, groupCnt, fishChan)  //通知fish
	go fish(fishChan, groupCnt, dogChan) //通知dog

	wg.Wait()
}

func fish(fishChan chan struct{}, cnt int, dogChan chan struct{}) {
	fishTimes := 0
	for fishTimes < cnt {
		select {
		case <-fishChan:
			fmt.Println("fish")
			fishTimes++

			//let fish run
			dogChan <- struct{}{}
		}
	}
	wg.Done()
}

func cat(catChan chan struct{}, cnt int, fishChan chan struct{}) {
	catTimes := 0

	for catTimes < cnt {
		select {
		case <-catChan:
			fmt.Println("cat")
			catTimes++

			//let fish run
			fishChan <- struct{}{}
		}
	}
	wg.Done()
}

func dog(dogChan chan struct{}, cnt int, catChan chan struct{}) {
	dogTimes := 0
	for dogTimes < cnt {
		select {
		case <-dogChan:
			fmt.Println("dog")
			dogTimes++

			//let cat run
			catChan <- struct{}{}
		}
	}

	wg.Done()
}

//OutPut:
/*
dog
cat
fish
dog
cat
fish
dog
cat
fish
*/
